package org.ws.task.netty.codec;

import io.protostuff.LinkedBuffer;
import io.protostuff.ProtobufIOUtil;
import io.protostuff.runtime.RuntimeSchema;
import org.ws.task.model.protocol.base.RequestMessage;
import org.ws.task.model.protocol.base.ResponseMessage;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public abstract class CodecUtil {

    private static Map<String, RuntimeSchema> schemaMap = new ConcurrentHashMap<>();

    private CodecUtil() {

    }

    /**
     *
     * @param obj
     * @return
     */
    public static byte [] encode(Object obj){
        Class<?> clazz = obj.getClass();
        String name = clazz.getName();
        if(!schemaMap.containsKey(name)){
            schemaMap.put(name,RuntimeSchema.createFrom(clazz));
        }
        RuntimeSchema<Object> schema = schemaMap.get(name);
        return ProtobufIOUtil.toByteArray(obj, schema,
                LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
    }

    /**
     *
     * @param data
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T decode(byte[]data,Class<T> clazz){
        String name = clazz.getName();
        if(!schemaMap.containsKey(name)){
            schemaMap.put(name,RuntimeSchema.createFrom(clazz));
        }
        RuntimeSchema<Object> schema = schemaMap.get(name);
        Object obj = schema.newMessage();
        ProtobufIOUtil.mergeFrom(data, obj, schema);
        return (T) obj;
    }

    public static int getType(Object obj){
        if(obj instanceof RequestMessage){
            return RequestMessage.MESSAGE_TYPE;
        }
        else if(obj instanceof ResponseMessage){
            return ResponseMessage.MESSAGE_TYPE;
        }
        return -1;
    }

    public static Class getClass(int type){
        if(RequestMessage.MESSAGE_TYPE == type){
            return RequestMessage.class;
        }
        if(ResponseMessage.MESSAGE_TYPE == type){
            return ResponseMessage.class;
        }
        return null;
    }
}
